package compilador.lexico;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.Stack;

import compilador.sintactico.ParserVal;
//import java.util.Vector;

/**
 * @author  Matias
 */
public class AnalizadorLexico {

	/**
	 * @uml.property  name="tS"
	 * @uml.associationEnd  
	 */
	TablaSimbolos TS;
	/**
	 * @uml.property  name="l"
	 * @uml.associationEnd  
	 */
	LectorToken L;
	/**
	 * @uml.property  name="errores"
	 */
	List<Error> Errores ;
	
	Stack<Integer> nroLineaBloque;
	
	public AnalizadorLexico(String code){
		TS = new TablaSimbolos();
		//Errores = new Vector<Error>();
		L = new LectorToken(TS,code);
		TS.agregarSimbolo("Palabra reservada", "If");
		TS.agregarSimbolo("Palabra reservada", "else");
		TS.agregarSimbolo("Palabra reservada", "for");
		TS.agregarSimbolo("Palabra reservada", "print");
		TS.agregarSimbolo("Palabra reservada", "uint");
		TS.agregarSimbolo("Palabra reservada", "ulong");
		nroLineaBloque = new Stack<Integer>();
	}
	
	/**
	 * @return
	 * @uml.property  name="errores"
	 */
	public List<Error> getErrores(){
		return L.getErrores();
	}
	
	public Token getNextToken(){
		if (L.HasMoreElements())
			return L.getToken();
		else
			return null;
	}
	
	public TablaSimbolos getTablaSimbolos(){
		return TS;
	}
	
	public List<Token> getListToken(){
		Token t;
		List<Token> lstTokens = new ArrayList<Token>();
		while ((t = L.getToken()) != null){
			lstTokens.add(t);
		}
		return lstTokens;
	}
	
	public int yylex(ParserVal yylval){
		Token t=this.getNextToken();
		
		int map_val = 0;
		if ((t != null)&&(!t.getID().equals("")))
			map_val = (map(t));
		if (t!=null){
		if(map_val == 257){ // Si es un ID
			yylval=new ParserVal( t.getValor() ); 
		}
		else if(map_val == 258){ // Si es una CTE
			yylval=new ParserVal( t.getValor() ); 
		}
		else
			yylval=new ParserVal( t.getValor() );
		}
		
		if ((t != null) && (t.getValor().equals("if") || t.getValor().equals("for"))) 
			this.nroLineaBloque.push(L.getNroLinea());
		
		return map_val;

	}
	
	private int map(Token t){
		
		if (t.getID().equals("Identificador")) return 257;
		if (t.getID().equals("Constante")) return 258;
		if (t.getID().equals("Op. Relacional")) return 259;
		if (t.getID().equals("Palabra Reservada") && (t.getValor().equals("if"))) return 260;
		if (t.getID().equals("Palabra Reservada") && (t.getValor().equals("else"))) return 261;
		if (t.getID().equals("Palabra Reservada") && (t.getValor().equals("for"))) return 262;
		if (t.getID().equals("Palabra Reservada") && (t.getValor().equals("uint"))) return 263;
		if (t.getID().equals("Palabra Reservada") && (t.getValor().equals("print"))) return 264;
		if (t.getID().equals("Palabra Reservada") && (t.getValor().equals("ulong"))) return 265;
		if (t.getID().equals("Cadena")) return 266;
		if (t.getID().equals("Asignacion")) return 267;
		if (t.getID().equals("Puntos consecutivos")) return 268;
		else return ((int)t.getValor().charAt(0));
		
	}
	
	public void yyerror(String error){
		if (L != null){
		Error e = new Error(error,L.getNroLinea(),"");
		L.addError(e);
		}
	}
	
	public int getNroLinea() {
		return L.nroLinea;
	}
	
	public int getNroLineaFromPila() {
		if (! nroLineaBloque.empty())
			return (int) nroLineaBloque.pop();
		else
			return L.nroLinea;
	}
	
}

